package com.qfmy.core.filter;

import com.qfmy.common.pojo.LoginUser;
import com.qfmy.common.pojo.TokenVo;
import com.qfmy.common.utils.StringUtils;
import com.qfmy.core.base.service.TokenService;
import com.qfmy.core.constant.CommonConstants;
import com.qfmy.core.pojo.entity.ErrorCode;
import com.qfmy.core.pojo.exception.CustomException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述:
 *      Security Token认证过滤器
 *      用于解析请求中的token，确保Token的存在与正确性
 *      继承 OncePerRequestFilter ，作用是：保证请求经过过滤器一次
 * @author zhengjt
 * @date 2022-10-28 15:44:22
 */
@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        log.info(" ========== 进入Token认证过滤器 ========== ");

        //  获取token
        String token = request.getHeader(CommonConstants.AUTH_TOKEN);

        //  判断token是否存在
        if (StringUtils.isEmpty(token)){
            log.info(" ========== token为空 ========== ");
            //放行,因为后面的会抛出相应的异常
            filterChain.doFilter(request, response);
            return;
        }

        //  校验token
//        boolean checkToken = tokenService.checkToken(token);
//        if (!checkToken){
//            throw new RuntimeException(ErrorCode.TOKEN_PARSE_ERROR.getMessage());
//        }
        TokenVo tokenVo = null;
        try {
            tokenVo = tokenService.getTokenVo(token);
            if (tokenVo == null){
                throw new RuntimeException(ErrorCode.TOKEN_PARSE_ERROR.getMessage());
            }
        }catch (CustomException e){
            log.error("Security Token认证过滤器 -- token解析异常 ： \n{}", e.getErrorCode().getMessage());
            filterChain.doFilter(request, response);
            return;
        }



        // TODO 此处尚未想好如何整合Security与我的思路，似乎有点冲突，待思考完成后此处需要完善
        LoginUser loginUser = new LoginUser();
        loginUser.setTokenUser(tokenVo);
        List<String> list = new ArrayList<>();
        list.add("LOGIN_MENU");
        list.add("TEST_MENU");
        loginUser.setPermissions(list);


        // 将Authentication对象（用户信息、已认证状态、权限信息）存入 SecurityContextHolder
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(tokenVo, null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);

        log.info(" ========== 离开Token认证过滤器 ========== ");
    }
}
